package librecalcdataproxy.client;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Date;

/**
 * Interfejs dostępowy usługi RMI
 * @author Wiktor Toporek
 */
public interface LibreCalcDataProxy extends Remote {
    
    /**
     * Otwiera nowy (pusty) arkusz kalkulacyjny.
     * @return Indeks dostępowy nowo-utworzonego dokumentu
     * @throws RemoteException 
     */
    int openNewSpreadsheet() throws RemoteException;
    
    /**
     * Otwiera istniejący dokument zapisany na dysku.
     * @param filepath Ścieżka do pliku
     * @return Indeks dostępowy otartego dokumentu
     * @throws RemoteException 
     */
    int openExistingSpreadsheet(String filepath) throws RemoteException;
    
    /**
     * Zerwanie powiązania pomiędzy tą usługą RMI a instancją otwartego dokumentu.
     * Proces ten odbywa się poprzez zwolnienie indeksu dokumentu.
     * Uwaga! Instancja LibreOffice Calc z otwartym dokumentem pozostaje uruchomiona.
     * @param documentIndex Indeks dokumentu do zwolnienia
     * @throws RemoteException 
     */
    void freeSpreadsheet(int documentIndex) throws RemoteException;

    /**
     * Zerwanie powiązania pomiędzy wszystkimi otwartymi dokumentami.
     * @see #freeSpreadsheet(int) 
     * @throws RemoteException 
     */
    void freeAllSpreadsheets() throws RemoteException;
    
    /**
     * Wyszukiwanie używanych/niezwolnionych otwartych indeksów po których można 
     * komunikować się z dokumentami arkuszów kalkukacyjnych
     * @return Tablica z dostępnymi indeksami
     * @throws RemoteException 
     */
    public int[] openedIndexes() throws RemoteException;
    
    
    /**
     * Wybór arkusza (zakładki) aktualnie obsługiwanego
     * @param documentIndex Indeks otwartego dokumentu
     * @param sheetIndex Indeks arkusza
     * @throws RemoteException 
     * @return Zwraca true w przypadku pomyślnego wybrania arkusza o podanym indeksie
     */
    boolean selectSheet(int documentIndex, int sheetIndex) throws RemoteException;
    
    /**
     * Ustawia wartość liczbową komórki o podanych współrzędnych
     * @param documentIndex Indeks otwartego dokumentu
     * @param x Współrzędna pozioma komórki liczona od 0
     * @param y Współrzędna pionowa komórki liczona od 0
     * @param value Wartość liczbowa która ma zostać wpisana do komórki
     * @throws RemoteException 
     */
    void setCell(int documentIndex, int x, int y, double value) throws RemoteException;
    
    /**
     * Wstawia tekst do komórki o podanych współrzędnych
     * @param documentIndex Indeks otwartego dokumentu
     * @param x Współrzędna pozioma komórki liczona od 0
     * @param y Współrzędna pionowa komórki liczona od 0
     * @param value Ciąg znaków który ma zostać wpisany
     * @throws RemoteException 
     */
    void setCell(int documentIndex, int x, int y, String value) throws RemoteException;
    
    /**
     * Wstawia datę w postaci tekstu w komórkę o podanych współrzędnych
     * @param documentIndex Indeks otwartego dokumentu
     * @param x Współrzędna pozioma komórki liczona od 0
     * @param y Współrzędna pionowa komórki liczona od 0
     * @param value Data do wpisania
     * @throws RemoteException 
     */
    void setCell(int documentIndex, int x, int y, Date value) throws RemoteException;
    
    /**
     * Pobiera wartość komórki o podanych współrzędnych
     * @param documentIndex Indeks otwartego dokumentu
     * @param x Współrzędna pozioma komórki liczona od 0
     * @param y Współrzędna pionowa komórki liczona od 0
     * @return Uniwersalny obiekt pozwalający na odczytanie wartości zarówno liczbowej jak i tekstowej
     * @throws RemoteException 
     * @see CellValue
     */
    CellValue getCellValue(int documentIndex, int x, int y) throws RemoteException;
    
    /**
     * Pobiera wartość tekstową komórki o podanych współrzędnych. 
     * W przypadku gdy wartość w komórce jest liczbowa, zostaje przekonwertowana na ciąg znaków
     * @param documentIndex Indeks otwartego dokumentu
     * @param x Współrzędna pozioma komórki liczona od 0
     * @param y Współrzędna pionowa komórki liczona od 0
     * @return Tekst w komórce
     * @throws RemoteException 
     */
    String getCellValueString(int documentIndex, int x, int y) throws RemoteException;
    
    /**
     * Pobiera wartość liczbową komórki o podanych współrzędnych. W przypadku gdy
     * typ wartości przechowywanej w komórce nie jest liczbą, zostanie wyrzucony wyjątek
     * NumberFormatException
     * @param documentIndex Indeks otwartego dokumentu
     * @param x Współrzędna pozioma komórki liczona od 0
     * @param y Współrzędna pionowa komórki liczona od 0
     * @return Wartość liczbowa komórki
     * @throws RemoteException
     * @throws NumberFormatException
     */
    double getCellValueDouble(int documentIndex, int x, int y) throws RemoteException,NumberFormatException;
    
    //Dopinanie GUI odpowiedzialnego za eksport (menu kontekstowe w LibreOffice -> export data)
    
    /**
     * Podpięcie do menu kontekstowego w arkuszu kalkulacyjnym (pod prawym przyciskiem myszy)
     * opcji która ma wyzwolić eksport danych
     * @param documentIndex Indeks otwartego dokumentu
     * @throws RemoteException 
     * @return True w przypadku pomyślnego podpięcia
     */
    boolean hookExportUI(int documentIndex) throws RemoteException;
    
    /**
     * Procedura wstrzymująca działanie programu do czasu kilknięcia opcji 
     * eksportu danych w arkuszu kalkulacyjnym
     * @throws RemoteException 
     */
    void waitForDataExport(int documentIndex) throws RemoteException;
    
    /**
     * Pobranie aktualnie zaznaczonych przez użytkownika obszarów komórek.
     * @param documentIndex Indeks otwartego dokumentu
     * @return Tablica zaznaczonych prostokątnych obszarów
     * @throws RemoteException 
     * @see CellsRange
     */
    CellsRange[] getSelectedCellsRange(int documentIndex) throws RemoteException;
    
}
